package com.bsg.upm.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.bsg.upm.constant.UserRoleConstants;
import com.bsg.upm.dao.DefinitionMetricTypeDao;
import com.bsg.upm.dto.SelectDto;
import com.bsg.upm.entity.AreaEntity;
import com.bsg.upm.entity.BackupStorageEntity;
import com.bsg.upm.entity.BusinessSubSystemEntity;
import com.bsg.upm.entity.BusinessSystemEntity;
import com.bsg.upm.entity.ClusterEntity;
import com.bsg.upm.entity.ComboEntity;
import com.bsg.upm.entity.DefinitionMetricTypeEntity;
import com.bsg.upm.entity.DefinitionServEntity;
import com.bsg.upm.entity.DefinitionSubServArchEntity;
import com.bsg.upm.entity.DefinitionSubServSoftwareEntity;
import com.bsg.upm.entity.DefinitionSubServUnitScaleEntity;
import com.bsg.upm.entity.DictEntity;
import com.bsg.upm.entity.DictTypeEntity;
import com.bsg.upm.entity.HostEntity;
import com.bsg.upm.entity.NetworkingEntity;
import com.bsg.upm.entity.PrivilegeEntity;
import com.bsg.upm.entity.SanEntity;
import com.bsg.upm.entity.SanVendorEntity;
import com.bsg.upm.entity.SiteEntity;
import com.bsg.upm.entity.SubServSoftwareImageEntity;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.entity.UserGroupEntity;
import com.bsg.upm.entity.UserRoleEntity;

/**
 * SELECT控件内容获取
 * 
 * @author HCK
 *
 */
@Service
public class SelectService extends BaseService {

	@Resource
	DefinitionMetricTypeDao definitionMetricTypeDao;

	/**
	 * 用户角色SELECT内容获取
	 * 
	 * @return 用户角色集合
	 */
	public List<SelectDto> listUserRoleName() {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<UserRoleEntity> roles = userRoleDao.listName();
		for (UserRoleEntity role : roles) {
			SelectDto select = new SelectDto();
			select.setId(role.getCode());
			select.setText(role.getName());
			select.setDescription(role.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 用户组SELECT内容获取
	 * 
	 * @return 用户组集合
	 */
	public List<SelectDto> listUserGroupName() {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<UserGroupEntity> groups = userGroupDao.listName();
		for (UserGroupEntity group : groups) {
			SelectDto select = new SelectDto();
			select.setId(group.getId());
			select.setText(group.getName());
			select.setDescription(group.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 站点SELECT内容获取
	 * 
	 * @return 站点集合
	 */
	public List<SelectDto> listSiteName() {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<SiteEntity> sites = siteDao.listName();
		for (SiteEntity site : sites) {
			SelectDto select = new SelectDto();
			select.setId(site.getId());
			select.setText(site.getName());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 备份存储SELECT内容获取
	 * 
	 * @param siteId
	 *            站点编码
	 * @param enabled
	 *            可用
	 * @return 备份存储集合
	 */
	public List<SelectDto> listBackupStorageName(String siteId, Boolean enabled) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<BackupStorageEntity> backups = backupStorageDao.listName(siteId, enabled);
		for (BackupStorageEntity backupStorage : backups) {
			SelectDto select = new SelectDto();
			select.setId(backupStorage.getId());
			select.setText(backupStorage.getName());
			select.setDescription(backupStorage.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 区域SELECT内容获取
	 * 
	 * @param siteId
	 *            站点编码
	 * @param enabled
	 *            可用
	 * @return 区域集合
	 */
	public List<SelectDto> listAreaName(String siteId, Boolean enabled) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<AreaEntity> areas = areaDao.listName(siteId, enabled);
		for (AreaEntity area : areas) {
			SelectDto select = new SelectDto();
			select.setId(area.getId());
			select.setText(area.getName());
			select.setDescription(area.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 未使用的网段SELECT内容获取
	 * 
	 * @param siteId
	 *            站点编码
	 * @param enabled
	 *            可用
	 * @return 区域集合
	 */
	public List<SelectDto> listUnusedNetworkingName(String siteId, Boolean enabled) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<NetworkingEntity> networkings = networkingDao.listUnusedName(siteId, enabled);
		for (NetworkingEntity networking : networkings) {
			SelectDto select = new SelectDto();
			select.setId(networking.getId());
			select.setText(networking.getName());
			select.setDescription(networking.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 集群SELECT内容获取
	 * 
	 * @param areaId
	 *            区域编码
	 * @param enabled
	 *            可用
	 * @return 集群集合
	 */
	public List<SelectDto> listClusterName(String areaId, Boolean enabled) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<ClusterEntity> clusters = clusterDao.listName(areaId, enabled);
		for (ClusterEntity cluster : clusters) {
			SelectDto select = new SelectDto();
			select.setId(cluster.getId());
			select.setText(cluster.getName());
			select.setDescription(cluster.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 主机SELECT内容获取
	 * 
	 * @param siteId
	 *            站点编码
	 * @param clusterId
	 *            集群编码
	 * @return 集群集合
	 */
	public List<SelectDto> listHostName(String siteId, String clusterId) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<HostEntity> hosts = hostDao.listName(siteId, clusterId);
		for (HostEntity host : hosts) {
			SelectDto select = new SelectDto();
			select.setId(host.getId());
			select.setText(host.getName());
			select.setDescription(host.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 主机SELECT内容获取
	 * 
	 * @param siteId
	 *            站点编码
	 * @return 集群集合
	 */
	public List<SelectDto> listSanName(String siteId) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<SanEntity> sans = sanDao.listName(siteId);
		for (SanEntity san : sans) {
			SelectDto select = new SelectDto();
			select.setId(san.getId());
			select.setText(san.getName());
			select.setDescription(san.getDescription());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 软件SELECT内容获取
	 * 
	 * @return 软件集合
	 */
	public List<SelectDto> listSoftware() {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<String> dfSubServNames = definitionSubServDao.listName();
		for (String dfSubServName : dfSubServNames) {
			SelectDto select = new SelectDto();
			select.setId(dfSubServName);
			select.setText(dfSubServName);
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 软件主次版本SELECT内容获取
	 * 
	 * @param definitionSubServName
	 *            子服务定义名称
	 * @return 软件集合
	 */
	public List<SelectDto> listSoftwareMajorAndMinorVersion(String definitionSubServName) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		if (StringUtils.isNotBlank(definitionSubServName)) {
			List<DefinitionSubServSoftwareEntity> dfSubServSoftwares = definitionSubServSoftwareDao
					.listMainAndMinorVersion(definitionSubServName);
			for (DefinitionSubServSoftwareEntity dfSubServSoftware : dfSubServSoftwares) {
				SelectDto select = new SelectDto();
				select.setId(dfSubServSoftware.getId());
				select.setText(dfSubServSoftware.getMajorVersion() + "." + dfSubServSoftware.getMinorVersion());
				selects.add(select);
			}
		}
		return selects;
	}

	/**
	 * 业务系统SELECT内容获取
	 * 
	 * @return 业务系统集合
	 */
	public List<SelectDto> listBusinessSystemName() {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		String username = getUser().getUsername();
		List<BusinessSystemEntity> businessSystems = businessSystemDao.listNameByOwner(username);
		for (BusinessSystemEntity businessSystem : businessSystems) {
			SelectDto select = new SelectDto();
			select.setId(businessSystem.getId());
			select.setText(businessSystem.getName());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 业务子系统SELECT内容获取
	 * 
	 * @return 业务系统集合
	 */
	public List<SelectDto> listBusinessSubSystemName(String businessSystemId) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<BusinessSubSystemEntity> businessSubSystems = businessSubSystemDao
				.listNameByBusinessSystemId(businessSystemId);
		for (BusinessSubSystemEntity businessSubSystem : businessSubSystems) {
			SelectDto select = new SelectDto();
			select.setId(businessSubSystem.getId());
			select.setText(businessSubSystem.getName());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 子服务架构SELECT内容获取
	 * 
	 * @param definitionServCode
	 *            服务定义代码
	 * @param definitionSubServName
	 *            子服务定义名
	 * @return 架构集合
	 */
	public List<SelectDto> listArchName(String definitionServCode, String definitionSubServName) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<DefinitionSubServArchEntity> archs = definitionSubServArchDao.listArchName(definitionServCode,
				definitionSubServName);
		for (DefinitionSubServArchEntity arch : archs) {
			SelectDto select = new SelectDto();
			select.setId(arch.getId());
			select.setText(arch.getName());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 子服务架构SELECT内容获取
	 * 
	 * @param definitionServCode
	 *            服务定义代码
	 * @param definitionSubServName
	 *            子服务定义名
	 * @return 架构集合
	 */
	public List<SelectDto> listAccessPointNum(String definitionServCode, String definitionSubServName) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<DefinitionSubServArchEntity> archs = definitionSubServArchDao.listUnitNum(definitionServCode,
				definitionSubServName);
		for (DefinitionSubServArchEntity arch : archs) {
			SelectDto select = new SelectDto();
			select.setId(arch.getId());
			select.setText(String.valueOf(arch.getUnitNum()));
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 子服务架构SELECT内容获取
	 * 
	 * @param definitionServCode
	 *            服务定义代码
	 * @param definitionSubServName
	 *            子服务定义名
	 * @return 架构集合
	 */
	public List<SelectDto> listScaleName(String definitionServCode, String definitionSubServName) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<DefinitionSubServUnitScaleEntity> scales = definitionSubServUnitScaleDao.listScaleName(definitionServCode,
				definitionSubServName);
		for (DefinitionSubServUnitScaleEntity scale : scales) {
			SelectDto select = new SelectDto();
			select.setId(scale.getId());
			select.setText(scale.getName());
			selects.add(select);
		}
		return selects;
	}

	public List<SelectDto> listVersion(String siteId, String definitionSubServName, Boolean enabled) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		UserEntity user = getUser();
		if (user == null) {
			return selects;
		}
		List<SubServSoftwareImageEntity> images = subServSoftwareImageDao.listSubServSoftwareImageVersion(siteId,
				definitionSubServName, enabled);
		if (UserRoleConstants.TENANT.equals(user.getUserRole().getCode())) {
			List<SubServSoftwareImageEntity> results = new ArrayList<>();
			for (SubServSoftwareImageEntity image : images) {
				DefinitionSubServSoftwareEntity dfSoftware = image.getDefinitionSubServSoftware();
				SubServSoftwareImageEntity result = findImage(results, dfSoftware.getDefinitionSubServName(),
						dfSoftware.getMajorVersion(), dfSoftware.getMinorVersion(), image.getPatchVersion());
				if (result == null) {
					results.add(image);
				} else {
					if (result.getBuildVersion().intValue() < image.getBuildVersion().intValue()) {
						results.remove(result);
						results.add(image);
					}
				}
			}

			for (SubServSoftwareImageEntity image : results) {
				SelectDto select = new SelectDto();
				select.setId(image.getId());
				DefinitionSubServSoftwareEntity dfSoftware = image.getDefinitionSubServSoftware();
				String text = dfSoftware.getMajorVersion() + "." + dfSoftware.getMinorVersion() + "."
						+ image.getPatchVersion();
				select.setText(text);
				select.setDescription(image.getDescription());
				selects.add(select);
			}
		} else {
			for (SubServSoftwareImageEntity image : images) {
				SelectDto select = new SelectDto();
				select.setId(image.getId());
				DefinitionSubServSoftwareEntity dfSoftware = image.getDefinitionSubServSoftware();
				String text = dfSoftware.getMajorVersion() + "." + dfSoftware.getMinorVersion() + "."
						+ image.getPatchVersion() + "." + image.getBuildVersion();
				select.setText(text);
				select.setDescription(image.getDescription());
				selects.add(select);
			}
		}
		return selects;
	}

	private SubServSoftwareImageEntity findImage(List<SubServSoftwareImageEntity> images, String softwareType,
			int majorVersion, int minorVersion, int patchVersion) {
		for (SubServSoftwareImageEntity image : images) {
			DefinitionSubServSoftwareEntity dfSoftware = image.getDefinitionSubServSoftware();
			if (dfSoftware.getDefinitionSubServName().equals(softwareType)
					&& dfSoftware.getMajorVersion().intValue() == majorVersion
					&& dfSoftware.getMinorVersion().intValue() == minorVersion
					&& image.getPatchVersion() == patchVersion) {
				return image;
			}
		}
		return null;
	}

	/**
	 * 服务类型SELECT内容获取
	 * 
	 * @return 服务集合
	 */
	public List<SelectDto> listServType() {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<DefinitionServEntity> definitionServs = definitionServDao.listName();
		for (DefinitionServEntity definitionServ : definitionServs) {
			SelectDto select = new SelectDto();
			select.setId(definitionServ.getCode());
			select.setText(definitionServ.getName());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * SAN品牌SELECT内容获取
	 * 
	 * @return SAN品牌集合
	 */
	public List<SelectDto> listSanVendor() {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<SanVendorEntity> sanVendors = sanVendorDao.list(null);
		for (SanVendorEntity sanVendor : sanVendors) {
			SelectDto select = new SelectDto();
			select.setId(sanVendor.getId());
			select.setText(sanVendor.getName() + "(" + sanVendor.getVersion() + ")");
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 套餐SELECT内容获取
	 * 
	 * @return 套餐集合
	 */
	public List<SelectDto> listCombo(String definitionServCode) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		List<ComboEntity> combos = comboDao.listName(definitionServCode);
		for (ComboEntity combo : combos) {
			SelectDto select = new SelectDto();
			select.setId(combo.getId());
			select.setText(combo.getName());
			selects.add(select);
		}
		return selects;
	}

	/**
	 * 权限内容获取
	 * 
	 * @param enabled
	 *            可用
	 * @return 权限集合
	 */
	public List<SelectDto> listPrivilege(Boolean enabled) {
		List<SelectDto> selects = new ArrayList<SelectDto>();
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("enabled", enabled);
		List<PrivilegeEntity> privileges = privilegeDao.list(paramMap);
		for (PrivilegeEntity privilege : privileges) {
			SelectDto select = new SelectDto();
			select.setId(privilege.getCode());
			select.setText(privilege.getDescription());
			selects.add(select);
		}
		return selects;
	}

	// /**
	// * 服务SELECT内容获取
	// *
	// * @param definitionServCode
	// * @return
	// */
	// public List<SelectDto> listServName(String siteId, String
	// definitionServCode) {
	// List<SelectDto> selects = new ArrayList<SelectDto>();
	// UserEntity user = getUser();
	// if (user == null) {
	// return selects;
	// }
	// String owner = null;
	// if (UserRoleConstants.TENANT.equals(user.getUserRole().getCode())) {
	// owner = user.getLoginName();
	// }
	// List<ServEntity> servs = servDao.listName(siteId, definitionServId,
	// owner);
	// for (ServEntity serv : servs) {
	// SelectDto select = new SelectDto();
	// select.setId(serv.getId());
	// select.setText(serv.getBusinessSubSystem().getCode());
	// selects.add(select);
	// }
	// return selects;
	// }

	/**
	 * SELECT控件内容获取
	 * 
	 * @param selectType
	 *            SELECT类型
	 * @return SELECT列表
	 */
	public List<SelectDto> listName(String selectType) {
		List<SelectDto> selectList = new ArrayList<SelectDto>();
		List<DictTypeEntity> dictTypeList = dictTypeCache.listDictTypeFromCache();
		for (DictTypeEntity dictType : dictTypeList) {
			if (dictType.getCode().equals(selectType)) {
				List<DictEntity> dictList = dictType.getDicts();
				for (DictEntity dict : dictList) {
					SelectDto select = new SelectDto();
					select.setId(dict.getCode());
					select.setText(dict.getName());
					selectList.add(select);
				}
				break;
			}
		}
		return selectList;
	}

	public List<SelectDto> listMonitorTypeName() {

		List<SelectDto> selectList = new ArrayList<SelectDto>();
		List<DefinitionMetricTypeEntity> dictTypeList = definitionMetricTypeDao.list(null);

		for (DefinitionMetricTypeEntity dictType : dictTypeList) {
			SelectDto select = new SelectDto();
			select.setId(dictType.getType());
			select.setText(dictType.getTypeName());
			selectList.add(select);
		}
		return selectList;
	}

}
